package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.convert.Convert;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.anno.CacheType;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bifang.assistant.common.vo.BaseVO;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.cache.jetcache.utils.JetCacheUtils;
import com.bifang.engine.data.core.util.PagerUtil;
import com.bifang.module.base.core.helper.DictHelper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jwsoft.manager.common.constant.EduCache;
import com.jwsoft.manager.common.vo.eduBreakThrough.EduBreakThroughKeyVO;
import com.jwsoft.manager.common.vo.eduBreakThrough.EduBreakThroughQueryVO;
import com.jwsoft.manager.common.vo.eduBreakThrough.EduBreakThroughVO;
import com.jwsoft.manager.common.vo.eduBreakThroughDetail.EduBreakThroughDetailKeyVO;
import com.jwsoft.manager.common.vo.eduBreakThroughDetail.EduBreakThroughDetailQueryVO;
import com.jwsoft.manager.common.vo.eduBreakThroughDetail.EduBreakThroughDetailVO;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.core.dao.model.EduBreakThrough;
import com.jwsoft.manager.core.dao.model.EduBreakThroughDetail;
import com.jwsoft.manager.core.dao.model.EduSchool;
import com.jwsoft.manager.core.dao.service.EduBreakThroughDetailService;
import com.jwsoft.manager.core.dao.service.EduBreakThroughService;
import com.jwsoft.manager.core.dao.service.EduSchoolService;
import com.jwsoft.manager.core.integration.EduBreakThroughIntegration;
import com.jwsoft.manager.core.util.EduHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 突破学区管理业务实现类
 *
 * @author chenzh
 * @since 2023-06-08
 */
@ApiService(funcCode = "eduBreakThrough", title = "突破学区管理")
public class EduBreakThroughIntegrationImpl implements EduBreakThroughIntegration {

    @Autowired
    public EduBreakThroughService eduBreakThroughService;
    @Autowired
    private EduSchoolService eduSchoolService;
    @Autowired
    private EduHelper eduHelper;
    @Autowired
    private DictHelper dictHelper;
    @Autowired
    private EduBreakThroughDetailService eduBreakThroughDetailService;

    @Override
    @OpApi(funcCode = "eduBreakThrough0001", title = "突破学区管理分页查询", funcType = FuncTypeEnum.query)
    public PageInfo<EduBreakThroughVO> getList(EduBreakThroughQueryVO vo) {
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(20);
        }
        if (vo.getYear() == null) {
            vo.setYear(eduHelper.thisYear());
        }
        QueryWrapper<EduBreakThrough> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(StringUtils.isNotBlank(vo.getSchoolId()), EduBreakThrough::getSchoolId, vo.getSchoolId())
                .eq(vo.getYear() != null, EduBreakThrough::getYear, vo.getYear())
                .eq(StringUtils.isNotBlank(vo.getStatus()), EduBreakThrough::getStatus, vo.getStatus())
                .eq(StringUtils.isNotBlank(vo.getAreaCode()), EduBreakThrough::getAreaCode, vo.getAreaCode());

        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());

        List<EduBreakThrough> list = eduBreakThroughService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduBreakThrough> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduBreakThroughVO> resultList = Convert.toList(EduBreakThroughVO.class, pageInfo.getList());
        // 转义数据字典值
        // dictHelper.valueToName(resultList, Arrays.asList(DemoDictEnum.values()));
        for (EduBreakThroughVO eduBreakThroughVO : resultList) {
            eduBreakThroughVO.setAreaName(dictHelper.getAreaNameByCode(eduBreakThroughVO.getAreaCode()));
        }
        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "eduBreakThrough0002", title = "突破学区管理根据主键查询详情", funcType = FuncTypeEnum.query)
    public EduBreakThroughVO getById(EduBreakThroughKeyVO vo) {
        EduBreakThrough entity = eduBreakThroughService.getById(vo.getBreakThroughId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("查询不到详细信息!");
        }
        EduBreakThroughVO result = Convert.convert(EduBreakThroughVO.class, entity);
        result.setAreaName(dictHelper.getAreaNameByCode(result.getAreaCode()));
        return result;
    }

    /**
     * 保存前统一校验
     */
    @Override
    @OpApi(funcCode = "eduBreakThrough0003", title = "突破学区管理保存前校验", funcType = FuncTypeEnum.other, checkPrivilege = BoolEnum.FALSE)
    public void checkSave(EduBreakThroughVO vo) {
        if (StringUtils.isBlank(vo.getSchoolId())) {
            throw new AppException("突破学区的学校不能为空");
        }
        if (StringUtils.isBlank(vo.getStatus())) {
            vo.setStatus(BoolEnum.TRUE.getType());
        }
        if (vo.getYear() == null) {
            vo.setYear(eduHelper.thisYear());
        }

        EduSchoolVO eduSchoolVO = eduSchoolService.getDetail(vo.getSchoolId());
        if (eduSchoolVO == null) {
            throw new AppException("突破学区的学校不存在");
        }
        vo.setAreaCode(eduSchoolVO.getAreaCode());
        vo.setSchoolName(eduSchoolVO.getSchoolName());
        QueryWrapper<EduBreakThrough> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduBreakThrough::getYear, vo.getYear())
                .eq(EduBreakThrough::getSchoolId, vo.getSchoolId())
                .ne(vo.getBreakThroughId() != null, EduBreakThrough::getBreakThroughId, vo.getBreakThroughId());
        if (eduBreakThroughService.count(queryWrapper) > 0) {
            throw new AppException("本年度突破学区的学校已存在，如有问题，请修改");
        }
    }

    @Override
    @OpApi(funcCode = "eduBreakThrough0004", title = "突破学区管理新增", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduBreakThrough0004",
            operationName = "突破学区管理新增",
            dataType = "breakThroughId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduBreakThroughVO add(EduBreakThroughVO vo) {
        //保存前校验
        checkSave(vo);
        //保存数据
        EduBreakThrough entity = Convert.convert(EduBreakThrough.class, vo);
        eduBreakThroughService.save(entity);
        //将主键设置回vo使操作日志可以取到
        vo.setBreakThroughId(entity.getBreakThroughId());
        clearCache(entity.getSchoolId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduBreakThrough0005", title = "突破学区管理修改", funcType = FuncTypeEnum.update)
    @SaveOplog(
            operationType = "eduBreakThrough0005",
            operationName = "突破学区管理修改",
            dataType = "breakThroughId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduBreakThroughVO edit(EduBreakThroughVO vo) {
        if (ObjectUtils.isEmpty(vo.getBreakThroughId())) {
            throw new AppException("传入需要修改的主键不能为空!");
        }
        EduBreakThrough oldEntity = eduBreakThroughService.getById(vo.getBreakThroughId());
        if (ObjectUtils.isEmpty(oldEntity)) {
            throw new AppException("查询不到需要修改的信息!");
        }
        //保存前校验
        checkSave(vo);
        //保存数据
        EduBreakThrough entity = Convert.convert(EduBreakThrough.class, vo);
        eduBreakThroughService.updateById(entity);
        clearCache(entity.getSchoolId());
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduBreakThrough0006", title = "突破学区管理根据主键删除", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "eduBreakThrough0006",
            operationName = "突破学区管理删除",
            dataType = "breakThroughId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void del(EduBreakThroughKeyVO vo) {
        if (ObjectUtils.isEmpty(vo.getBreakThroughId())) {
            throw new AppException("传入需要删除的数据主键不能为空!");
        }
        EduBreakThrough entity = eduBreakThroughService.getById(vo.getBreakThroughId());
        if (ObjectUtils.isEmpty(entity)) {
            throw new AppException("未找到需要删除的信息!");
        }
        eduBreakThroughService.removeById(vo.getBreakThroughId());
        clearCache(entity.getSchoolId());
    }

    @Override
    @OpApi(funcCode = "eduBreakThrough0007", title = "突破学区管理根据主键查询关联学校列表", funcType = FuncTypeEnum.query)
    public PageInfo<EduBreakThroughDetailVO> getBreakSchoolQuery(EduBreakThroughDetailQueryVO vo) {
        if (vo.getBreakThroughId() == null) {
            throw new AppException("突破学区主键不能为空!");
        }
        // 开启分页
        if (vo.getPageNum() == null || vo.getPageSize() == null) {
            //如果不传入分页参数，默认最大取1000条
            vo.setPageNum(1);
            vo.setPageSize(20);
        }
        QueryWrapper<EduBreakThroughDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduBreakThroughDetail::getBreakThroughId, vo.getBreakThroughId());
        PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        List<EduBreakThroughDetail> list = eduBreakThroughDetailService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            // 判断是否为空，为空则返回空参数
            return PagerUtil.createEmptyPagerInfo(vo.getPageNum(), vo.getPageSize());
        }
        // 不为空则获取分页结果
        PageInfo<EduBreakThroughDetail> pageInfo = new PageInfo<>(list);
        // 返回参数需要通过common层的vo实体类，用该方法可以批量转换
        List<EduBreakThroughDetailVO> resultList = Convert.toList(EduBreakThroughDetailVO.class, pageInfo.getList());

        return PagerUtil.parsePagerVo(resultList, pageInfo);
    }

    @Override
    @OpApi(funcCode = "eduBreakThrough0008", title = "突破学区管理单个删除关联学校信息", funcType = FuncTypeEnum.delete)
    @SaveOplog(
            operationType = "eduBreakThrough0008",
            operationName = "突破学区管理单个删除关联学校信息",
            dataType = "breakThroughId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void delDetail(EduBreakThroughDetailKeyVO vo) {
        if (vo.getBreakThroughDetailId() == null) {
            throw new AppException("突破学区关联学校的明细id不能为空");
        }
        EduBreakThroughDetail detail = eduBreakThroughDetailService.getById(vo.getBreakThroughDetailId());
        if (detail == null) {
            throw new AppException("未找到关联学校明细信息");
        }
        EduBreakThrough breakThrough=eduBreakThroughService.getById(detail.getBreakThroughId());
        eduBreakThroughDetailService.removeById(vo.getBreakThroughDetailId());
        clearCache(detail.getSchoolId());
        if (breakThrough!=null){
            clearCache(breakThrough.getSchoolId());
        }

    }

    @Override
    @OpApi(funcCode = "eduBreakThrough0009", title = "突破学区管理单个新增关联学校信息", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduBreakThrough0009",
            operationName = "突破学区管理单个新增关联学校信息",
            dataType = "breakThroughId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public EduBreakThroughDetailVO addDetail(EduBreakThroughDetailVO vo) {
        if (vo.getBreakThroughId() == null) {
            throw new AppException("突破学区id不能为空");
        }
        if (StringUtils.isBlank(vo.getSchoolId())) {
            throw new AppException("可突破的学校id不能为空");
        }
        if (CollectionUtils.isEmpty(vo.getConfigNames())) {
            throw new AppException("可突破的报名类别不能为空");
        }

        QueryWrapper<EduBreakThroughDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduBreakThroughDetail::getBreakThroughId, vo.getBreakThroughId())
                .eq(EduBreakThroughDetail::getSchoolId, vo.getSchoolId());
        if (eduBreakThroughDetailService.count(queryWrapper) > 0) {
            throw new AppException("可突破的学校已存在，不能重复添加");
        }
        QueryWrapper<EduBreakThrough> throughQueryWrapper = new QueryWrapper<>();
        throughQueryWrapper.lambda().eq(EduBreakThrough::getBreakThroughId, vo.getBreakThroughId())
                .eq(EduBreakThrough::getSchoolId, vo.getSchoolId());
        if (eduBreakThroughService.count(throughQueryWrapper) > 0) {
            throw new AppException("不能将自己添加到可突破学校");
        }
        EduSchoolVO eduSchoolVO = eduSchoolService.getDetail(vo.getSchoolId());
        if (eduSchoolVO == null) {
            throw new AppException("可突破的学校信息不存在");
        }
        vo.setSchoolName(eduSchoolVO.getSchoolName());
        vo.setConfigNameList(vo.getConfigNames().stream().map(a -> a).collect(Collectors.joining(",")));
        EduBreakThroughDetail eduBreakThroughDetail = Convert.convert(EduBreakThroughDetail.class, vo);
        eduBreakThroughDetailService.save(eduBreakThroughDetail);
        vo.setBreakThroughDetailId(eduBreakThroughDetail.getBreakThroughDetailId());
        clearCache(eduBreakThroughDetail.getSchoolId());
        EduBreakThrough breakThrough=eduBreakThroughService.getById(eduBreakThroughDetail.getBreakThroughId());
        if (breakThrough!=null){
            clearCache(breakThrough.getSchoolId());
        }
        return vo;
    }

    @Override
    @OpApi(funcCode = "eduBreakThrough0010", title = "突破学区管理复制上年度数据", funcType = FuncTypeEnum.insert)
    @Transactional
    public void init(BaseVO vo) {
        Integer year=eduHelper.thisYear();
        if(year==null){
            throw new AppException("系统年度参数未配置");
        }
        QueryWrapper<EduBreakThrough> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda().eq(EduBreakThrough::getYear,year);
        if(eduBreakThroughService.count(queryWrapper)>0){
            throw new AppException("年度数据已存在，不能初始化");
        }
        QueryWrapper<EduBreakThrough> sndQuery=new QueryWrapper<>();
        sndQuery.lambda().eq(EduBreakThrough::getYear,year-1);
        List<EduBreakThrough> list=eduBreakThroughService.list(sndQuery);
        if(CollectionUtils.isEmpty(list)){
            throw new AppException("上年度数据不存在存在，不能初始化");
        }
        for(EduBreakThrough eduBreakThrough:list){
            Long id=eduBreakThrough.getBreakThroughId();
            eduBreakThrough.setYear(year);
            eduBreakThrough.setBreakThroughId(null);
            eduBreakThroughService.save(eduBreakThrough);
            QueryWrapper<EduBreakThroughDetail> detailQueryWrapper=new QueryWrapper<>();
            detailQueryWrapper.lambda().eq(EduBreakThroughDetail::getBreakThroughId,id);
            List<EduBreakThroughDetail> detailList=eduBreakThroughDetailService.list(detailQueryWrapper);
            if(!CollectionUtils.isEmpty(detailList)){
                for(EduBreakThroughDetail detail:detailList){
                    detail.setBreakThroughId(eduBreakThrough.getBreakThroughId());
                    detail.setBreakThroughDetailId(null);
                    clearCache(eduBreakThrough.getSchoolId());
                }
                eduBreakThroughDetailService.saveBatch(detailList);
            }
            clearCache(eduBreakThrough.getSchoolId());
        }
    }
    private void clearCache(String orgId) {
        if (StringUtils.isNotBlank(orgId)) {
            Cache cache = JetCacheUtils.create(EduCache.EDU_SCHOOL_DETAIL, CacheType.BOTH);
            if (cache != null) {
                cache.remove(orgId);
            }
        }
    }
}
